package com.amado.easyui2.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.amado.easyui2.constant.GlobalConstants;
import com.amado.easyui2.dao.UserDao;
import com.amado.easyui2.domain.Department;
import com.amado.easyui2.domain.User;
import com.amado.easyui2.service.DepartmentService;
import com.amado.easyui2.service.UserService;
import com.amado.easyui2.util.JsonUtil;
import com.amado.easyui2.util.Md5Util;
import com.amado.easyui2.vo.Result;
import com.amado.easyui2.vo.UpdatePasswordVO;
import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class UserLoginServlet extends HttpServlet {
	private UserService userService;
	private DepartmentService departmentService;
	private static final long serialVersionUID = 1L;
	ApplicationContext applicationContext;

	@Override
	public void init() throws ServletException {
		// Spring容器
		applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
		// 通过容器获取Bean
		userService = applicationContext.getBean("userServiceImpl", UserService.class);
		departmentService = applicationContext.getBean(DepartmentService.class);
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		resp.setHeader("Content-type", "text/html;charset=UTF-8");
		String method = req.getParameter("method");
		if ("login".equals(method)) {
			login(req, resp);
		} else if ("loginOut".equals(method)) {
			loginOut(req, resp);
		} else if ("updatePassword".equals(method)) {
			updatePassword(req, resp);
		}
	}

	List<Date> listDate = new ArrayList<>();
	// 记录错误的次数
	Map<String, List<Date>> errorMap = new HashMap<>();

	/**
	 * 登录
	 * 
	 * @param req请求数据
	 * @param resp    响应数据
	 * @throws ServletException
	 * @throws IOException
	 */
       
	private void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		String userNum = req.getParameter("userNum");
		String password =Md5Util.encode((req.getParameter("password")));
		String verifyCode = req.getParameter("verifyCode");
		String sessionVerifyCode = (String) req.getSession(false).getAttribute("verifyCode");
		if (sessionVerifyCode == null || !sessionVerifyCode.equals(verifyCode)) {
			req.setAttribute("msg", "验证码错误");
			req.getRequestDispatcher("login.jsp").forward(req, resp);
			return;
		}
		// 检查是否通过（小于3次返回true）
//		boolean eliminate = eliminateAndCheck();
		boolean eliminate = eliminateAndCheck(userNum);
		// 不通过
		if (!eliminate) {
			req.setAttribute("msg", "密码输入超过三次账号已被锁定，1天之后再尝试");
			req.getRequestDispatcher("login.jsp").forward(req, resp);
			return;
		}
		// 通过
		User user = userService.getBy(userNum);
		if (user != null && user.getPassword().equals(password)) {
			req.getSession().setAttribute(GlobalConstants.SESSION_USER, userNum);
			buildDeptName(user);
			req.getSession().setAttribute(GlobalConstants.SESSION_USER_ALL, user);
//			listDate.clear();
			errorMap.remove(userNum);
			resp.sendRedirect("index.jsp");
		} else {
//			this.countLogin();
//			listDate.add(new Date());
			setErrorCount(userNum);
			req.setAttribute("msg", "密码错误，请重新输入");
			req.getRequestDispatcher("login.jsp").forward(req, resp);
		}
	}

	public void buildDeptName(User user) {
		Department dept = departmentService.getByDeptNumber(user.getDepartmentNum());
		if(dept!=null) {
			user.setDepartmentName(dept.getDepartmentName());
		}
	}
	/**
	 * Map<String,List<Date>>
	 * 
	 * @param userName
	 */
	public void setErrorCount(String userName) {
		// 得到错误登陆记录
		List<Date> listDate = errorMap.get(userName);
		// 如果没记录，添加一条记录
		if (listDate == null) {
			// 初始化一个空的记录
			listDate = new ArrayList();
			errorMap.put(userName, listDate);
		}
		listDate.add(new Date());
	}

	/**
	 * 记录错误次数 防止用户输入在规定的时间清理系统记录
	 * 
	 * @author Administrator
	 *
	 */
	public class countLogin {
		HashMap<String, List<Date>> hashmap = new HashMap<String, List<Date>>();

		boolean iterator(String userName) {
			for (int hashmap = 0; hashmap <= 3; hashmap++) {
				if (hashmap <= 3) {
					hashmap++;
				} else {
					return false;
				}
			}
			return true;
		}
	}

	/**
	 * 清理并返回验证状态
	 * 
	 * @return
	 */
	private boolean eliminateAndCheck() {
		Iterator<Date> iterator = listDate.iterator();
		// 清理
		while (iterator.hasNext()) {
			Date tempDate = iterator.next();
			if (tempDate.getTime() + (1000 * 120) < System.currentTimeMillis()) {

				iterator.remove();
			}
		}
		// 检查
		if (listDate.size() >= 3) {
			System.out.println("密码输入超过三次");
			return false;
		}
		return true;

	}

	/**
	 * 检查用户，并清理用户的过期记录
	 * 
	 * @param userName 用户名
	 * @return 检查通过 返回true,失败返回false
	 */
	private boolean eliminateAndCheck(String userName) {
		List<Date> listDate = errorMap.get(userName);
		// 一次错误记录都没有（第一次登陆）
		if (listDate == null) {
			return true;
		}

		Iterator<Date> iterator = listDate.iterator();
		// 清理
		while (iterator.hasNext()) {
			Date tempDate = iterator.next();
			if (tempDate.getTime() + (1000 * 3600 * 24) < System.currentTimeMillis()) {
				iterator.remove();
			}
		}
		// 检查
		if (listDate.size() >= 3) {
			System.out.println("密码输入超过三次");
			return false;
		}
		return true;

	}

	private void updatePassword(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		// 1、request.parameter()旧密码、新密码
		String data = req.getParameter("data");
		UpdatePasswordVO updatePasswordVO = JsonUtil.jsonToBean(data, UpdatePasswordVO.class);
		// 2、获取session 用户名
		String userName = (String) req.getSession().getAttribute(GlobalConstants.SESSION_USER);
		// 3、调用service 处理业务逻辑
		boolean isSuccess = userService.updatePassword(userName, updatePasswordVO.getOldPassword(),
				updatePasswordVO.getNewPassword());
		if (isSuccess) {
			resp.getWriter().print(JsonUtil.beanToJson(new Result()));
		} else {
			resp.getWriter().print(JsonUtil.beanToJson(new Result("0", "旧密码错误")));
		}
		// 4、得到service 的结果，旧密码错误/修改成功
	}

	private void loginOut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		req.getSession().removeAttribute(GlobalConstants.SESSION_USER);// 注销
		resp.sendRedirect("login.jsp");
	}
}
